import * as vscode from "vscode";
import { VsCodeWebviewProtocol } from "./webviewProtocol";
import * as fs from 'fs';
import * as path from 'path';
import { MCPClient } from "../core/mcp/mcpClient";
import { LoginService } from "./services/loginService";
import axios from 'axios';
import * as os from 'os';
import { DocLinterWebviewRequestHandler } from "../plugins/actions/DocLinter/docLinterWebviewRequestHandler";
import { ProxyService } from './services/proxyService';
import { AiChatWebviewRequestHandler } from "../plugins/actions/AiChat/aiChatWebviewRequestHandler";
import { MCPClientAndProvider } from "../core/mcp/mcpClientAndProvider";

interface ToolCallChunk {
  index: number;
  id?: string;
  type?: 'function';
  function?: {
      name?: string;
      arguments?: string;
  };
}

export class HarmonyPilotGUIWebviewViewProvider implements vscode.WebviewViewProvider {
  private _webview?: vscode.Webview;
  public webviewProtocol: VsCodeWebviewProtocol;
  private loginService: LoginService;
  private proxyService: ProxyService;
  private currentPage: string = '/aichat';
  private cookiePath: string;
  private isZh: boolean;
  private configUrl: string;
  private mcpClientAndProvider?: MCPClientAndProvider;

  get webview() {
    return this._webview;
  }

  constructor(
    private readonly _extensionUri: vscode.Uri,
    private readonly _mode: vscode.ExtensionMode,
    private context: vscode.ExtensionContext,
    private mcpClient: MCPClient
  ) {
    this.webviewProtocol = new VsCodeWebviewProtocol(this._webview);
    this.context = context;
    this.loginService = LoginService.getInstance(context);
    this.proxyService = ProxyService.getInstance(context);
    
    // 初始化配置
    this.cookiePath = this.getVSCodeConfigDir() + '/cookie.txt';
    this.isZh = this.getLocale().includes("zh");
    this.configUrl = this.getServerUrl();
  }

  /**
   * 设置MCP客户端和提供者的引用
   * @param mcpClientAndProvider MCP客户端和提供者实例
   */
  public setMcpClientAndProvider(mcpClientAndProvider: MCPClientAndProvider): void {
    this.mcpClientAndProvider = mcpClientAndProvider;
  }

  resolveWebviewView(webviewView: vscode.WebviewView) {
    this._webview = webviewView.webview;
    this.webviewProtocol._webview = this._webview;
    webviewView.webview.options = {
      // 在 webview 允许脚本
      enableScripts: true,
      localResourceRoots: [this._extensionUri],
    };

    //  判断是debug还是生产
    //  vscode.ExtensionMode.Production - 扩展从marketplace或VSIX安装并正常运行时
    //  vscode.ExtensionMode.Development - 扩展在开发模式下运行，通常是通过F5或VSCode调试时
    const inDevelopmentMode = this._mode === vscode.ExtensionMode.Development;
    if (!inDevelopmentMode) {
      webviewView.webview.html = this.getProductionHtml(webviewView.webview);
    } else {
      webviewView.webview.html = this.getDebugHtml(webviewView.webview);
    }


    
    const aiChatWebviewRequestHandler = new AiChatWebviewRequestHandler(this.context, this.webviewProtocol);

    webviewView.webview.onDidReceiveMessage(
      async (message) => {
        
        switch (message.messageType) {
          // webview页面加载时获取主题
          case "getTheme":
            const isDark =
            vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.Dark;
              webviewView.webview.postMessage({
                messageType: "themeChange",
                data: {
                  isDark,
                },
              });
            break;
          case "requestMcpTools":
            await this.handleRequestMcpTools();
            break;
          case "insertCode":
            this.insertCode(message.data);
            break;
          case "copyText":
            this.copyText(message.data);
            break;
          case "notification":
            // 显示通知消息
            vscode.window.showInformationMessage(message.data);
            break;
          case "wait":
            // 显示等待消息
            vscode.window.showInformationMessage(message.data);
            break;
          case "chatRequest":
            aiChatWebviewRequestHandler.chatRequest(message);
            break;
          case "stopChatRequest":
            aiChatWebviewRequestHandler.stopChatRequest();
            break;
          case "toolCallsDetected":
            const result = await this.mcpClient.getResult(message.data.toolCalls);
            this.webviewProtocol.send("toolCallsResult", {
              messageType: "toolCallsResult",
              data: result,
            });
            break;
          // 检查是否登录
          case "checkAuthStatus":
            await this.handleCheckAuthStatus();
            break;
          case "openThirdPartyLogin":
            await this.handleThirdPartyLogin();
            break;
          case "copy":
            await this.setCopyText(message.data || "");
            this._webview?.postMessage({
              messageType: "copyCallback",
              data: "success",
            });
            break;
          case "queryStatus":
            await this.handleQueryStatus(message.data);
            break;
          case "raise":
            await this.handleRaise(message.data);
            break;
          case "logOut":
            await this.handleLogOut();
            break;
          case "queryHasLogin":
            await this.handleQueryHasLogin();
            break;
          case "login":
            await this.handleLogin();
            break;
          case "replace":
            await this.handleReplace(message.data);
            break;
          case "compare":
            await this.handleCompare(message.data);
            break;
          case "lang":
            this.handleLang();
            break;
          case "theme":
            this.handleTheme();
            break;
          case "viewReport":
            await this.handleViewReport(message.data);
            break;
          case "goToFile":
            await this.handleGoToFile(message.data);
            break;
          case "openExternal":
            this.handleOpenExternal(message.data);
            break;
          case "downLoad":
            await this.handleDownload(message.data);
            break;
          case "cancel":
            await this.handleCancel(message.data);
            break;
          default:
            vscode.window.showInformationMessage(message.data);
            break;
        }
      },
      undefined,
      this.context.subscriptions
    );
    // 监听主题变化
    vscode.window.onDidChangeActiveColorTheme((theme) => {
      const isDark = theme.kind === vscode.ColorThemeKind.Dark;
      webviewView.webview.postMessage({
        messageType: "themeChange",
        data: {
          isDark,
        },
      });
    });
  }

  getDebugHtml(webview: vscode.Webview) {
    const staticPath = String(
      webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri))
    );
    const fontUri = String(
      webview.asWebviewUri(
        vscode.Uri.file(
          path.join(
            this._extensionUri.fsPath,
            "webview_ui/dist/assets",
            "devui-icomoon.woff"
          )
        )
      )
    );
    const code = fs.readFileSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui/dist/index.html"),
      "utf-8"
    );
    const files = fs.readdirSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui/dist/assets")
    );
    let jsFile = "";
    let cssFile = "";
    for (const file of files) {
      if (file.endsWith("js")) {
        jsFile = file;
      } else if (file.endsWith("css")) {
        cssFile = file;
      } else {
      }
    }
    const curPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui/dist/assets",
      jsFile
    );
    const curCssPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui/dist/assets",
      cssFile
    );
    const jsSrc = this.webview?.asWebviewUri(curPath);
    const cssSrc = this.webview?.asWebviewUri(curCssPath);
    let result = code.replace(/<script.*?src="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/src="(.+?)"/, (src: string) => {
        return `src="${jsSrc}"`;
      });
    });
    result = result.replace(/<link.*?href="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/href="(.+?)"/, (src: string) => {
        return `href="${cssSrc}"`;
      });
    });
    result = result.replaceAll("${staticPath}", staticPath);
    result = result.replace("${fontUri}", fontUri);
    
    // 确保默认进入aichat页面
    result = result.replace(
      "window.vscode = window.acquireVsCodeApi && window.acquireVsCodeApi();",
      `window.vscode = window.acquireVsCodeApi && window.acquireVsCodeApi();
       // 设置默认hash路由
       if (!window.location.hash) {
         window.location.hash = '#/aichat';
       }`
    );
    
    return result;
  }

  getProductionHtml(webview: vscode.Webview) {
    const staticPath = String(
      webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri))
    );
    const fontUri = String(
      webview.asWebviewUri(
        vscode.Uri.file(
          path.join(
            this._extensionUri.fsPath,
            "webview_ui/dist/assets",
            "devui-icomoon.woff"
          )
        )
      )
    );
    const code = fs.readFileSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui/dist/index.html"),
      "utf-8"
    );
    const files = fs.readdirSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui/dist/assets")
    );
    let jsFile = "";
    let cssFile = "";
    for (const file of files) {
      if (file.endsWith("js")) {
        jsFile = file;
      } else if (file.endsWith("css")) {
        cssFile = file;
      } else {
      }
    }
    const curPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui/dist/assets",
      jsFile
    );
    const curCssPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui/dist/assets",
      cssFile
    );
    const jsSrc = this.webview?.asWebviewUri(curPath);
    const cssSrc = this.webview?.asWebviewUri(curCssPath);
    let result = code.replace(/<script.*?src="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/src="(.+?)"/, (src: string) => {
        return `src="${jsSrc}"`;
      });
    });
    result = result.replace(/<link.*?href="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/href="(.+?)"/, (src: string) => {
        return `href="${cssSrc}"`;
      });
    });
    result = result.replaceAll("${staticPath}", staticPath);
    result = result.replace("${fontUri}", fontUri);
    
    // 确保默认进入aichat页面
    result = result.replace(
      "window.vscode = window.acquireVsCodeApi && window.acquireVsCodeApi();",
      `window.vscode = window.acquireVsCodeApi && window.acquireVsCodeApi();
       // 设置默认hash路由
       if (!window.location.hash) {
         window.location.hash = '#/aichat';
       }`
    );
    
    return result;
  }
  insertCode(data: any) {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      vscode.window.showErrorMessage("无活动编辑器！");
      return;
    }
    const codeSnippet = (data.code as string)
      .replace(/\\/g, "\\\\")
      .replace(/\$/g, "\\$");
    // 执行插入操作
    vscode.window.activeTextEditor?.insertSnippet(new vscode.SnippetString(codeSnippet));
  }

  copyText(data: any) {
    vscode.env.clipboard.writeText(data.code).then(() => {
      vscode.window.showInformationMessage("复制成功！");
    });
  }

  /**
   * 处理检查认证状态
   */
  private async handleCheckAuthStatus(): Promise<void> {
    try {
      const isLoggedIn = await this.loginService.isLoggedIn();
      if (isLoggedIn) {
        const apiKey = this.getApiKey();
        this._webview?.postMessage({
          messageType: "authStatusResult",
          data: {
            isLoggedIn: true,
            apiKey: apiKey
          }
        });
      } else {
        this._webview?.postMessage({
          messageType: "authStatusResult",
          data: {
            isLoggedIn: false,
            apiKey: null
          }
        });
      }
    } catch (error) {
      console.error('检查认证状态失败:', error);
      this._webview?.postMessage({
        messageType: "authStatusResult",
        data: {
          isLoggedIn: false,
          apiKey: null
        }
      });
    }
  }

  /**
   * 处理第三方登录
   */
  private async handleThirdPartyLogin(): Promise<void> {
    try {
      // 启动登录流程，使用回调机制
      await this.loginService.startLogin({
        onSuccess: (userInfo) => {
          console.log('登录成功:', userInfo);
          const apiKey = this.getApiKey();
          
          this._webview?.postMessage({
            messageType: "thirdPartyLoginSuccess",
            data: {
              userInfo: userInfo,
              apiKey: apiKey
            }
          });
        },
        onFailure: (reason, message) => {
          console.error('登录失败:', reason, message);
          this._webview?.postMessage({
            messageType: "thirdPartyLoginFailed",
            data: {
              reason: reason,
              message: message
            }
          });
        }
      });
      
    } catch (error) {
      console.error('启动第三方登录失败:', error);
      this._webview?.postMessage({
        messageType: "thirdPartyLoginFailed",
        data: {
          reason: "startup_error",
          message: `启动登录失败: ${error}`
        }
      });
    }
  }

  /**
   * 获取 API Key
   */
  private getApiKey(): string | null {
    try {
      const configPath = path.join(this._extensionUri.fsPath, 'core', 'llm-config.json');
      if (fs.existsSync(configPath)) {
        const configData = fs.readFileSync(configPath, 'utf-8');
        const config = JSON.parse(configData);
        return config.apiKey || null;
      }
      return null;
    } catch (error) {
      console.error('获取 API Key 失败:', error);
      return null;
    }
  }

  /**
   * 验证登录状态并发送相应消息
   */
  public async validateAndNotifyLoginStatus(): Promise<void> {
    try {
      const isValid = await this.loginService.validateSession();
      
      if (!isValid) {
        this._webview?.postMessage({
          messageType: "loginRequired",
          data: {
            message: "登录信息已过期，请重新登录"
          }
        });
      } else {
        const apiKey = this.getApiKey();
        this._webview?.postMessage({
          messageType: "setApiKey",
          data: apiKey
        });
      }
    } catch (error) {
      console.error('验证登录状态失败:', error);
      this._webview?.postMessage({
        messageType: "loginRequired",
        data: {
          message: "验证登录状态失败，请重新登录"
        }
      });
    }
  }

  /**
   * 清理资源
   */
  public dispose(): void {
    if (this.loginService) {
      this.loginService.dispose();
    }
  }

  public toggleDocLinterView() {
    this.currentPage = this.currentPage === '/aichat' ? '/doclinter' : '/aichat';
    this._webview?.postMessage({
      messageType: 'navigateTo',
      data: {
        page: this.currentPage,
      },
    });
  }


  public goToDocLinterView() {
    this.currentPage = '/doclinter';
    this._webview?.postMessage({
      messageType: 'navigateTo',
      data: {
        page: this.currentPage,
      },
    });
  }

  public async updateLoginStatus() {
    if (this._webview) {
        const isLoggedIn = await this.loginService.isLoggedIn();
        const userInfo = isLoggedIn ? await this.loginService.getUserInfo() : null;
        this._webview.postMessage({
            messageType: 'loginStatusChanged',
            data: {
                isLoggedIn,
                userInfo,
            },
        });
    }
  }

  /**
   * 获取 VSCode 配置目录
   */
  private getVSCodeConfigDir(): string {
    const configPath = 
      process.env?.LOCALAPPDATA ||
      process.env?.VSCODE_CWD ||
      process.env?.USERPROFILE ||
      process.env?.ProgramFiles ||
      os.homedir();
    
    return configPath;
  }

  /**
   * 获取语言设置
   */
  private getLocale(): string {
    return vscode.env.language || 'en';
  }

  /**
   * 获取服务器 URL
   */
  private getServerUrl(): string {
    const urls = {
      DEV: process.env.DEV_URL!,
      BETA: process.env.BETA_URL!,
      TEST: process.env.TEST_URL!,
      PROD: process.env.PROD_URL!
    };

    const env = (process.env.enviroment || 'DEV').toUpperCase();
    return urls[env as keyof typeof urls] || urls.DEV;
  }

  /**
   * 复制文本到剪贴板
   */
  private async setCopyText(text: string): Promise<void> {
    await vscode.env.clipboard.writeText(text);
  }

  /**
   * 获取文档中的位置信息
   */
  private getPosition(offset: number): { line: number; column: number } {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      return { line: 0, column: 0 };
    }
    
    const position = editor.document.positionAt(offset);
    return { line: position.line, column: position.character };
  }

  /**
   * 更新文本
   */
  private updateText(callback: (editBuilder: vscode.TextEditorEdit) => void): void {
    const editor = vscode.window.activeTextEditor;
    if (editor) {
      editor.edit(callback);
    }
  }

  /**
   * 获取国际化文本
   */
  private getI18nText() {
    return {
      zh: {
        loginTimeout: "登录信息已过期，请重新登录",
      },
      en: {
        loginTimeout: "Login information has expired, please log in again",
      }
    };
  }

  /**
   * 处理查询状态
   */
  private async handleQueryStatus(data: any): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      return;
    }
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    const { defectId } = data;
    const url = `${this.configUrl}/api/aiService/feedback/get?defectId=${defectId}`;
    
    try {
      const res = await axios.get(url, {
        headers: { cookie },
      });
      
      this._webview?.postMessage({
        messageType: "queryStatusCallback",
        data: {
          status: res.data.data,
        },
      });
    } catch (error: any) {
      console.error(`Failed to query likes and dislikes status, defectId is ${defectId}, error is ${error}`);
      if (error.response?.status === 401) {
        this.handleLoginTimeout();
      }
    }
  }

  /**
   * 处理反馈操作
   */
  private async handleRaise(data: any): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      return;
    }
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    const { reportId, defectId, status } = data;
    const url = `${this.configUrl}/api/aiService/feedback/set`;
    
    try {
      await axios.post(
        url,
        {
          reportId,
          defectId,
          status,
          reason: data.reason || "",
        },
        {
          headers: {
            cookie,
          },
        }
      );
      
      this._webview?.postMessage({
        messageType: "raiseCallback",
        data: {
          status,
        },
      });
    } catch (error: any) {
      console.error(`operation failed, defectId is ${defectId}, error is ${error}`);
      if (error.response?.status === 401) {
        this.handleLoginTimeout();
      }
    }
  }

  /**
   * 处理登出
   */
  private async handleLogOut(): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      this._webview?.postMessage({
        messageType: "logOutCallback",
        data: true,
      });
      return;
    }
    
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    
    try {
      await axios.get(`${this.configUrl}/api/gateway/logout`, {
        headers: {
          cookie,
        },
      });
      
      fs.unlinkSync(this.cookiePath);
      this._webview?.postMessage({
        messageType: "logOutCallback",
        data: true,
      });
    } catch (error) {
      console.error('Failed to log out', error);
      this._webview?.postMessage({
        messageType: "logOutCallback",
        data: false,
      });
    }
  }

  /**
   * 处理查询是否已登录
   */
  private async handleQueryHasLogin(): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      this._webview?.postMessage({
        messageType: "queryHasLoginCallback",
        data: {},
      });
      return;
    }
    
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    
    try {
      const res = await axios.post(
        `${this.configUrl}/api/aiService/user/getUser`,
        {},
        {
          headers: {
            cookie: cookie,
          },
        }
      );
      
      this._webview?.postMessage({
        messageType: "queryHasLoginCallback",
        data: {
          name: res.data.data.cnName,
        },
      });
    } catch (error: any) {
      console.error('User not logged in', error);
      if (error.response?.status === 401) {
        this.handleLoginTimeout();
      }
    }
  }

  /**
   * 处理登录
   */
  private async handleLogin(): Promise<void> {
    try {
      const res = await axios.get(`${this.configUrl}/api/login`);
      const url = res.data.loginUrl;
      const loginUrl = `${process.env.LOCAL_LOGIN_URL}/index?loginUrl=${url}`;
      vscode.env.openExternal(vscode.Uri.parse(loginUrl));
    } catch (error) {
      console.error('Login failed:', error);
      vscode.window.showErrorMessage('登录失败');
    }
  }

  /**
   * 处理登录超时
   */
  private handleLoginTimeout(): void {
    if (fs.existsSync(this.cookiePath)) {
      fs.unlinkSync(this.cookiePath);
      this._webview?.postMessage({
        messageType: "logOutCallback",
        data: true,
      });
      const i18nTexts = this.getI18nText();
      vscode.window.showErrorMessage(
        this.isZh ? i18nTexts.zh.loginTimeout : i18nTexts.en.loginTimeout
      );
    }
  }

  /**
   * 处理替换文本
   */
  private async handleReplace(data: any): Promise<void> {
    const { filePath, line, originText, fixText } = data;
    if (!fs.existsSync(filePath)) {
      // 当前文件不存在
      this._webview?.postMessage({
        messageType: "gotoFileCallback",
      });
      return;
    }
    
    const curText = fs.readFileSync(filePath, "utf-8");
    const list = curText.split("\n");
    let index = 0;
    for (let i = 0; i < line - 1; i++) {
      index += list[i].length + 1;
    }
    const nextIndex = curText
      .slice(index, curText.length)
      .indexOf(originText);
    if (nextIndex > -1) {
      const start = index + nextIndex;
      const end = start + originText.length;
      const pos1 = this.getPosition(start);
      const pos2 = this.getPosition(end);
      this.updateText((edit) => {
        edit.replace(
          new vscode.Range(
            new vscode.Position(pos1.line, pos1.column),
            new vscode.Position(pos2.line, pos2.column)
          ),
          fixText
        );
      });
    }
  }

  /**
   * 处理文件比较
   */
  private async handleCompare(data: any): Promise<void> {
    const { filePath, originText, fixText } = data;
    if (!fs.existsSync(filePath)) {
      // 当前文件不存在
      this._webview?.postMessage({
        messageType: "gotoFileCallback",
      });
      return;
    }
    
    const originData: string = fs.readFileSync(filePath, "utf-8");
    const list: string[] = filePath.split(".");
    const ext: string = list[list.length - 1];
    const DEFAULT_RULE_DIR = this.getVSCodeConfigDir();
    const nextPath: string = `${DEFAULT_RULE_DIR}/temp.${ext}`;
    const nextData: string = originData.replace(originText, fixText);
    fs.writeFileSync(nextPath, nextData);
    vscode.commands.executeCommand(
      "vscode.diff",
      vscode.Uri.file(nextPath),
      vscode.Uri.file(filePath),
      "advice->originText"
    );
  }

  /**
   * 处理语言查询
   */
  private handleLang(): void {
    const lang = this.getLocale();
    this._webview?.postMessage({
      messageType: "langCallback",
      data: lang,
    });
  }

  /**
   * 处理主题查询
   */
  private handleTheme(): void {
    const theme = vscode.window.activeColorTheme;
    this._webview?.postMessage({
      messageType: "themeCallback",
      data: theme.kind,
    });
  }

  /**
   * 处理查看报告
   */
  private async handleViewReport(reportId: string): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      return;
    }
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    const url = `${this.configUrl}/api/aiService/report/detail?reportId=${reportId}`;
    
    try {
      const res = await axios.get(url, { headers: { cookie } });
      this._webview?.postMessage({
        messageType: "viewReportCallback",
        data: res.data.data,
      });
    } catch (error: any) {
      console.error(`Failed to query record, error is ${error}`);
      if (error.response?.status === 401) {
        this.handleLoginTimeout();
      }
    }
  }

  /**
   * 处理跳转到文件
   */
  private async handleGoToFile(data: any): Promise<void> {
    const { filePath, line } = data;
    if (!fs.existsSync(filePath)) {
      // 当前文件不存在
      this._webview?.postMessage({
        messageType: "gotoFileCallback",
      });
      return;
    }
    
    let uri = vscode.Uri.file(filePath);
    vscode.commands.executeCommand("vscode.open", uri).then((res) => {
      let editor = vscode.window.activeTextEditor;
      if (editor) {
        const range = editor.document.lineAt(line - 1).range;
        editor.selection = new vscode.Selection(range.start, range.end);
        editor.revealRange(range);
      }
    });
  }

  /**
   * 处理打开外部链接
   */
  private handleOpenExternal(reportId: string): void {
    const url = `${process.env.DOCLINTER_REPORT_URL}/workbench/ai/docLinter/viewReport?reportId=${reportId}`;
    vscode.env.openExternal(vscode.Uri.parse(url));
  }

  /**
   * 处理下载
   */
  private async handleDownload(reportId: string): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      return;
    }
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    const url = `${this.configUrl}/api/aiService/report/export?reportId=${reportId}`;
    
    try {
      const res = await axios.get(url, { 
        headers: { 
          cookie
        }, 
        responseType: 'arraybuffer'
      });
      
      // 1. 从响应头获取文件名
      const contentDisposition = res.headers['content-disposition'];
      const fileName = contentDisposition?.split('filename=')[1] || `report_${Date.now()}.xlsx`;
      
      // 2. 弹出保存对话框
      const fileUri = await vscode.window.showSaveDialog({
        defaultUri: vscode.Uri.file(fileName),
        filters: { 'Excel Files': ['xlsx'] }
      });
      
      if (fileUri) {
        // 3. 将二进制数据写入文件
        fs.writeFileSync(fileUri.fsPath, Buffer.from(res.data));
        vscode.window.showInformationMessage(
          this.isZh ? `Excel 导出成功: ${fileUri.fsPath}` : `Excel exported: ${fileUri.fsPath}`
        );
      }
    } catch (error) {
      console.error(`导出失败: ${error}`);
      vscode.window.showErrorMessage(
        this.isZh ? 'Excel 导出失败' : 'Failed to export Excel'
      );
    }
  }

  /**
   * 处理取消报告
   */
  private async handleCancel(reportId: string): Promise<void> {
    if (!fs.existsSync(this.cookiePath)) {
      return;
    }
    const cookie = fs.readFileSync(this.cookiePath, "utf-8");
    const url = `${this.configUrl}/api/aiService/report/cancelReport?reportId=${reportId}`;
    
    try {
      const res = await axios.get(url, { headers: { cookie } });
      this._webview?.postMessage({
        messageType: "cancelCallback",
        data: res.data.data,
      });
    } catch (error: any) {
      console.error(`Failed to cancel report, error is ${error}`);
      if (error.response?.status === 401) {
        this.handleLoginTimeout();
      }
    }
  }

  /**
   * 处理请求MCP工具的消息
   */
  private async handleRequestMcpTools(): Promise<void> {
    if (this.mcpClientAndProvider) {
      await this.mcpClientAndProvider.refreshMcpTools();
    }
  }
}
